<!--
 * @Author: Leng
 * @Date: 2021-03-12 15:21:04
 * @Description: 倒计时
 * @FilePath: \vue-leng\src\components\module\countdown\index.vue
-->

<template>
  <div class="countdown-container" v-html="updateTimeCallBack"></div>
</template>

<script>
  let timeCounter = null
  const interval = 1000
  export default {
    name: "countdown",
    props: {
      // 需要执行的时间差
      modelValue: null,
      contentFn: Function
    },
    data () {
      return {
        count: 0,
        startTime: new Date().getTime(),
        // 当前倒计时时间
        currentTime: null
      }
    },

    mounted () {
      if (!this.currentTime && this.modelValue) {
        this.currentTime = this.modelValue
        timeCounter = setTimeout(this.countDownStart, interval)
      }
    },

    computed: {
      updateTimeCallBack () {
        if (this.contentFn && this.currentTime >= 0) {
          return this.contentFn(this.getFormatTime(this.currentTime))
        }
        return ''
      }
    },

    methods: {
      countDownStart () {
        this.count++
        const offset = new Date().getTime() - (this.startTime + this.count * interval)
        let nextTime = interval - offset
        if (nextTime < 0) {
          nextTime = 0
        }
        this.currentTime -= interval
        if (this.currentTime < 0) {
          clearTimeout(timeCounter)
        } else {
          timeCounter = setTimeout(this.countDownStart, nextTime)
        }
      },

      getFormatTime (timeDiff) {
        let times = timeDiff / 1000
        let d = Math.floor(times / (60 * 60 * 24))
        let h = Math.floor(times / (60 * 60)) - (d * 24)
        let m = Math.floor(times / 60) - (d * 24 * 60) - (h * 60)
        let s = Math.floor(times) - (d * 24 * 60 * 60) - (h * 60 * 60) - (m * 60)
        return {d, h, m, s}
      }
    },

    watch: {
      value (val) {
        if (!this.currentTime && val) {
          this.currentTime = val
          timeCounter = setTimeout(this.countDownStart, interval)
        } else {
          this.currentTime = val
        }
      },
      currentTime (val) {
        this.$emit('input', val)
      }
    }
  }
</script>

<style lang="scss" scoped>

</style>
